package ynu.edu.controller;

import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import jakarta.annotation.Resource;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.*;
import ynu.edu.entity.User;
import ynu.edu.feign.ServiceProviderService;

import java.time.LocalDateTime;
import java.util.Map;

@RestController
@RequestMapping("/feign")
@RefreshScope  // 配置更新域
public class FeignDemoController {
    
    @Resource
    private ServiceProviderService serviceProviderService;
    
    /**
     * 使用OpenFeign进行GET调用 - 根据ID获取用户（使用熔断器A保护）
     */
    @GetMapping("/getUserById/{userId}")
    @CircuitBreaker(name = "circuitBreakerA", fallbackMethod = "getUserByIdFallback")
    public User getUserById(@PathVariable("userId") Integer userId) {
        return serviceProviderService.GetUserById(userId);
    }
    
    /**
     * 熔断器A的降级方法 - getUserById
     */
    public User getUserByIdFallback(Integer userId, Exception ex) {
        User fallbackUser = new User();
        fallbackUser.setUserId(userId);
        fallbackUser.setUserName("降级用户-" + userId);
        fallbackUser.setPassWord("fallback123");
        return fallbackUser;
    }
    
    /**
     * 使用OpenFeign进行GET调用 - 获取所有用户（使用熔断器B保护）
     */
    @GetMapping("/getAllUsers")
    @CircuitBreaker(name = "circuitBreakerB", fallbackMethod = "getAllUsersFallback")
    public Map<String, Object> getAllUsers() {
        return serviceProviderService.getAllUsers();
    }
    
    /**
     * 熔断器B的降级方法 - getAllUsers
     */
    public Map<String, Object> getAllUsersFallback(Exception ex) {
        return Map.of(
                "status", "FALLBACK",
                "message", "熔断器B触发 - 服务降级中",
                "timestamp", LocalDateTime.now(),
                "data", java.util.List.of(
                        Map.of("userId", 1, "userName", "降级用户1", "passWord", "fallback123"),
                        Map.of("userId", 2, "userName", "降级用户2", "passWord", "fallback123")
                ),
                "total", 2,
                "error", ex.getMessage()
        );
    }
    
    /**
     * 使用OpenFeign进行POST调用 - 创建用户（使用熔断器A保护）
     */
    @PostMapping("/createUser")
    @CircuitBreaker(name = "circuitBreakerA", fallbackMethod = "createUserFallback")
    public Map<String, Object> createUser(@RequestBody User user) {
        return serviceProviderService.createUser(user);
    }
    
    /**
     * 熔断器A的降级方法 - createUser
     */
    public Map<String, Object> createUserFallback(User user, Exception ex) {
        return Map.of(
                "status", "FALLBACK",
                "message", "熔断器A触发 - 用户创建服务降级",
                "timestamp", LocalDateTime.now(),
                "originalUser", user,
                "error", ex.getMessage(),
                "fallbackResponse", "用户创建请求已记录，将稍后处理"
        );
    }
    
    /**
     * 使用OpenFeign进行PUT调用 - 更新用户（使用熔断器B保护）
     */
    @PutMapping("/updateUser/{userId}")
    @CircuitBreaker(name = "circuitBreakerB", fallbackMethod = "updateUserFallback")
    public Map<String, Object> updateUser(@PathVariable("userId") Integer userId, @RequestBody User user) {
        return serviceProviderService.updateUser(userId, user);
    }
    
    /**
     * 熔断器B的降级方法 - updateUser
     */
    public Map<String, Object> updateUserFallback(Integer userId, User user, Exception ex) {
        return Map.of(
                "status", "FALLBACK",
                "message", "熔断器B触发 - 用户更新服务降级",
                "timestamp", LocalDateTime.now(),
                "userId", userId,
                "originalUser", user,
                "error", ex.getMessage(),
                "fallbackResponse", "用户更新请求已记录，将稍后处理"
        );
    }
    
    /**
     * 使用OpenFeign进行DELETE调用 - 删除用户（使用熔断器A保护）
     */
    @DeleteMapping("/deleteUser/{userId}")
    @CircuitBreaker(name = "circuitBreakerA", fallbackMethod = "deleteUserFallback")
    public Map<String, Object> deleteUser(@PathVariable("userId") Integer userId) {
        return serviceProviderService.deleteUser(userId);
    }
    
    /**
     * 熔断器A的降级方法 - deleteUser
     */
    public Map<String, Object> deleteUserFallback(Integer userId, Exception ex) {
        return Map.of(
                "status", "FALLBACK",
                "message", "熔断器A触发 - 用户删除服务降级",
                "timestamp", LocalDateTime.now(),
                "userId", userId,
                "error", ex.getMessage(),
                "fallbackResponse", "用户删除请求已记录，将稍后处理"
        );
    }
    
    /**
     * 负载均衡测试接口 - 多次调用查看负载均衡效果（使用熔断器B保护）
     */
    @GetMapping("/loadBalanceTest")
    @CircuitBreaker(name = "circuitBreakerB", fallbackMethod = "loadBalanceTestFallback")
    public Map<String, Object> loadBalanceTest() {
        // 连续调用10次，观察随机负载均衡效果
        java.util.List<String> results = new java.util.ArrayList<>();
        int count11000 = 0;
        int count11001 = 0;
        
        for (int i = 0; i < 10; i++) {
            Map<String, Object> response = serviceProviderService.getAllUsers();
            if (response != null && response.get("message") != null) {
                String message = response.get("message").toString();
                results.add("第" + (i + 1) + "次调用: " + message);
                
                // 统计调用分布
                if (message.contains("from 11000")) {
                    count11000++;
                } else if (message.contains("from 11001")) {
                    count11001++;
                }
            }
        }
        
        return Map.of(
                "testType", "OpenFeign随机负载均衡测试",
                "strategy", "Random LoadBalancer",
                "results", results,
                "statistics", Map.of(
                        "total", 10,
                        "server11000", count11000,
                        "server11001", count11001,
                        "distribution", count11000 + ":" + count11001
                ),
                "explanation", "随机策略：观察调用分布应该是随机的，不是1:1轮询"
        );
    }
    
    /**
     * 熔断器B的降级方法 - loadBalanceTest
     */
    public Map<String, Object> loadBalanceTestFallback(Exception ex) {
        return Map.of(
                "testType", "OpenFeign随机负载均衡测试 - 降级响应",
                "status", "FALLBACK",
                "strategy", "Circuit Breaker B Activated",
                "timestamp", LocalDateTime.now(),
                "error", ex.getMessage(),
                "message", "熔断器B已开启，负载均衡测试暂时不可用",
                "fallbackResults", java.util.List.of(
                        "降级响应：服务暂时不可用",
                        "请稍后重试"
                )
        );
    }
} 